{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "import h5py\n",
    "import numpy as np\n",
    "from sklearn.utils import shuffle\n",
    "np.random.seed(2017)\n",
    "\n",
    "X_train = []\n",
    "X_test = []\n",
    "\n",
    "for filename in [\"gap_ResNet50.h5\", \"gap_Xception.h5\", \"gap_InceptionV3.h5\"]:\n",
    "    with h5py.File(filename, 'r') as h:\n",
    "        X_train.append(np.array(h['train']))\n",
    "        X_test.append(np.array(h['test']))\n",
    "        y_train = np.array(h['label'])\n",
    "\n",
    "X_train = np.concatenate(X_train, axis=1)\n",
    "X_test = np.concatenate(X_test, axis=1)\n",
    "\n",
    "X_train, y_train = shuffle(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.models import *\n",
    "from keras.layers import *\n",
    "\n",
    "input_tensor = Input(X_train.shape[1:])\n",
    "x = input_tensor\n",
    "x = Dropout(0.5)(x)\n",
    "x = Dense(1, activation='sigmoid')(x)\n",
    "model = Model(input_tensor, x)\n",
    "\n",
    "model.compile(optimizer='adadelta',\n",
    "              loss='binary_crossentropy',\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg height=\"215pt\" viewBox=\"0.00 0.00 282.68 215.00\" width=\"283pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 211)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"#ffffff\" points=\"-4,4 -4,-211 278.6797,-211 278.6797,4 -4,4\" stroke=\"transparent\"/>\n",
       "<!-- 5722972816 -->\n",
       "<g class=\"node\" id=\"node1\">\n",
       "<title>5722972816</title>\n",
       "<polygon fill=\"none\" points=\"0,-162.5 0,-206.5 274.6797,-206.5 274.6797,-162.5 0,-162.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"64.1812\" y=\"-180.3\">input_1: InputLayer</text>\n",
       "<polyline fill=\"none\" points=\"128.3623,-162.5 128.3623,-206.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"156.1968\" y=\"-191.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"128.3623,-184.5 184.0313,-184.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"156.1968\" y=\"-169.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"184.0313,-162.5 184.0313,-206.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"229.3555\" y=\"-191.3\">(None, 6144)</text>\n",
       "<polyline fill=\"none\" points=\"184.0313,-184.5 274.6797,-184.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"229.3555\" y=\"-169.3\">(None, 6144)</text>\n",
       "</g>\n",
       "<!-- 4591509648 -->\n",
       "<g class=\"node\" id=\"node2\">\n",
       "<title>4591509648</title>\n",
       "<polygon fill=\"none\" points=\".3794,-81.5 .3794,-125.5 274.3003,-125.5 274.3003,-81.5 .3794,-81.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"64.1812\" y=\"-99.3\">dropout_1: Dropout</text>\n",
       "<polyline fill=\"none\" points=\"127.9829,-81.5 127.9829,-125.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"155.8174\" y=\"-110.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"127.9829,-103.5 183.6519,-103.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"155.8174\" y=\"-88.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"183.6519,-81.5 183.6519,-125.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"228.9761\" y=\"-110.3\">(None, 6144)</text>\n",
       "<polyline fill=\"none\" points=\"183.6519,-103.5 274.3003,-103.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"228.9761\" y=\"-88.3\">(None, 6144)</text>\n",
       "</g>\n",
       "<!-- 5722972816&#45;&gt;4591509648 -->\n",
       "<g class=\"edge\" id=\"edge1\">\n",
       "<title>5722972816-&gt;4591509648</title>\n",
       "<path d=\"M137.3398,-162.3664C137.3398,-154.1516 137.3398,-144.6579 137.3398,-135.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"140.8399,-135.6068 137.3398,-125.6068 133.8399,-135.6069 140.8399,-135.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "<!-- 4343560784 -->\n",
       "<g class=\"node\" id=\"node3\">\n",
       "<title>4343560784</title>\n",
       "<polygon fill=\"none\" points=\"12.0552,-.5 12.0552,-44.5 262.6245,-44.5 262.6245,-.5 12.0552,-.5\" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"64.1812\" y=\"-18.3\">dense_1: Dense</text>\n",
       "<polyline fill=\"none\" points=\"116.3071,-.5 116.3071,-44.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"144.1416\" y=\"-29.3\">input:</text>\n",
       "<polyline fill=\"none\" points=\"116.3071,-22.5 171.9761,-22.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"144.1416\" y=\"-7.3\">output:</text>\n",
       "<polyline fill=\"none\" points=\"171.9761,-.5 171.9761,-44.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"217.3003\" y=\"-29.3\">(None, 6144)</text>\n",
       "<polyline fill=\"none\" points=\"171.9761,-22.5 262.6245,-22.5 \" stroke=\"#000000\"/>\n",
       "<text fill=\"#000000\" font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"217.3003\" y=\"-7.3\">(None, 1)</text>\n",
       "</g>\n",
       "<!-- 4591509648&#45;&gt;4343560784 -->\n",
       "<g class=\"edge\" id=\"edge2\">\n",
       "<title>4591509648-&gt;4343560784</title>\n",
       "<path d=\"M137.3398,-81.3664C137.3398,-73.1516 137.3398,-63.6579 137.3398,-54.7252\" fill=\"none\" stroke=\"#000000\"/>\n",
       "<polygon fill=\"#000000\" points=\"140.8399,-54.6068 137.3398,-44.6068 133.8399,-54.6069 140.8399,-54.6068\" stroke=\"#000000\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import SVG\n",
    "from keras.utils.visualize_util import model_to_dot, plot\n",
    "\n",
    "SVG(model_to_dot(model, show_shapes=True).create(prog='dot', format='svg'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 20000 samples, validate on 5000 samples\n",
      "Epoch 1/8\n",
      "20000/20000 [==============================] - 1s - loss: 0.1193 - acc: 0.9591 - val_loss: 0.0283 - val_acc: 0.9936\n",
      "Epoch 2/8\n",
      "20000/20000 [==============================] - 0s - loss: 0.0319 - acc: 0.9898 - val_loss: 0.0181 - val_acc: 0.9952\n",
      "Epoch 3/8\n",
      "20000/20000 [==============================] - 0s - loss: 0.0252 - acc: 0.9916 - val_loss: 0.0172 - val_acc: 0.9934\n",
      "Epoch 4/8\n",
      "20000/20000 [==============================] - 0s - loss: 0.0214 - acc: 0.9936 - val_loss: 0.0140 - val_acc: 0.9956\n",
      "Epoch 5/8\n",
      "20000/20000 [==============================] - 0s - loss: 0.0200 - acc: 0.9926 - val_loss: 0.0139 - val_acc: 0.9954\n",
      "Epoch 6/8\n",
      "20000/20000 [==============================] - 0s - loss: 0.0189 - acc: 0.9933 - val_loss: 0.0129 - val_acc: 0.9956\n",
      "Epoch 7/8\n",
      "20000/20000 [==============================] - 0s - loss: 0.0170 - acc: 0.9946 - val_loss: 0.0123 - val_acc: 0.9960\n",
      "Epoch 8/8\n",
      "20000/20000 [==============================] - 0s - loss: 0.0163 - acc: 0.9945 - val_loss: 0.0119 - val_acc: 0.9958\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x15541db90>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(X_train, y_train, batch_size=128, nb_epoch=8, validation_split=0.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "model.save('model.h5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11968/12500 [===========================>..] - ETA: 0s"
     ]
    }
   ],
   "source": [
    "y_pred = model.predict(X_test, verbose=1)\n",
    "y_pred = y_pred.clip(min=0.005, max=0.995)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 12500 images belonging to 1 classes.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.995</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>0.995</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>0.995</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>0.995</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0.005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>0.005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>7</td>\n",
       "      <td>0.005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>8</td>\n",
       "      <td>0.005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>9</td>\n",
       "      <td>0.005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>10</td>\n",
       "      <td>0.005</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   id  label\n",
       "0   1  0.995\n",
       "1   2  0.995\n",
       "2   3  0.995\n",
       "3   4  0.995\n",
       "4   5  0.005\n",
       "5   6  0.005\n",
       "6   7  0.005\n",
       "7   8  0.005\n",
       "8   9  0.005\n",
       "9  10  0.005"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "from keras.preprocessing.image import *\n",
    "\n",
    "df = pd.read_csv(\"sample_submission.csv\")\n",
    "\n",
    "image_size = (224, 224)\n",
    "gen = ImageDataGenerator()\n",
    "test_generator = gen.flow_from_directory(\"test2\", image_size, shuffle=False, \n",
    "                                         batch_size=16, class_mode=None)\n",
    "\n",
    "for i, fname in enumerate(test_generator.filenames):\n",
    "    index = int(fname[fname.rfind('/')+1:fname.rfind('.')])\n",
    "    df.set_value(index-1, 'label', y_pred[i])\n",
    "\n",
    "df.to_csv('pred.csv', index=None)\n",
    "df.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
